package cn.gailvlun.gll.presentation.hotel.night

import android.app.Activity
import android.databinding.DataBindingUtil
import android.os.Bundle
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.PagerSnapHelper
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import cn.gailvlun.gll.R
import cn.gailvlun.gll.bean.PlaceHolder
import cn.gailvlun.gll.databinding.FragmentHotelBrowseBinding
import cn.gailvlun.gll.net.HttpMethods
import cn.gailvlun.gll.net.HttpSubscriber
import cn.gailvlun.gll.net.ListRes
import cn.gailvlun.gll.net.NewQueryParam
import cn.gailvlun.gll.net.hotel.*
import cn.gailvlun.gll.presentation.base.App
import cn.gailvlun.gll.presentation.base.BaseActivity
import cn.gailvlun.gll.presentation.base.BaseFragment
import cn.gailvlun.gll.presentation.hotel.night.HotelCommentActivity.Companion.openActivityForResult
import cn.gailvlun.gll.presentation.profile.OtherProfileActivity
import cn.gailvlun.gll.presentation.profile.ProfileActivity
import cn.gailvlun.gll.util.*
import cn.gailvlun.gll.widget.OnPlayViewStateChangedListener
import cn.gailvlun.gll.widget.PlayViewState
import com.freeze.horizontalrefreshlayout.lib.HorizontalRefreshLayout
import com.freeze.horizontalrefreshlayout.lib.RefreshCallBack
import com.freeze.horizontalrefreshlayout.lib.refreshhead.MaterialRefreshHeader
import com.github.markzhai.recyclerview.BaseViewAdapter
import io.reactivex.functions.Consumer


class HotelBrowseFragment : BaseFragment(), RefreshCallBack {

    private lateinit var mBinding: FragmentHotelBrowseBinding

    private var mAdapter: HotelBrowseAdapter? = null
    private lateinit var mLayoutManager: LinearLayoutManager

    private var insomniaCategory: InsomniaCategory? = null
    private var insomniaType: InsomniaType? = null

    private val newQueryParam = NewQueryParam()

    private var currentPos: Int = 0
    override fun isLazyLoad() = true
    private lateinit var mPagerSnapHelper: PagerSnapHelper

    companion object {
        fun newInstance(category: InsomniaCategory?, type: InsomniaType): HotelBrowseFragment {
            val fragment = HotelBrowseFragment()
            val bundle = Bundle()
            bundle.putSerializable("category", category)
            bundle.putSerializable("type", type)
            fragment.arguments = bundle
            return fragment
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        insomniaCategory = arguments.getSerializable("category") as InsomniaCategory?
        insomniaType = arguments.getSerializable("type") as InsomniaType?
    }

    override fun onVisible() {
        super.onVisible()
        onLeftRefreshing()
        mAdapter?.notifyDataSetChanged()
    }

    override fun onInVisible() {
        super.onInVisible()
        mBinding.pv.stop()
    }

    override fun initComponent(inflater: LayoutInflater, container: ViewGroup?): View {
        mBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_hotel_browse, container, false)
        mBinding.presenter = Presenter()

        mAdapter = HotelBrowseAdapter(mContext)
        mAdapter!!.setPresenter(Presenter())
        mBinding.recyclerView.adapter = mAdapter

        mLayoutManager = LinearLayoutManager(mContext, LinearLayoutManager.HORIZONTAL, false)
        mBinding.recyclerView.layoutManager = mLayoutManager

        mPagerSnapHelper = PagerSnapHelper()
        mPagerSnapHelper.attachToRecyclerView(mBinding.recyclerView)

        mBinding.hrl.setRefreshMode(HorizontalRefreshLayout.MODE_UNDER_FOLLOW_DRAG)
        mBinding.hrl.setRefreshHeader(MaterialRefreshHeader(HorizontalRefreshLayout.START), HorizontalRefreshLayout.START)
        mBinding.hrl.setRefreshHeader(MaterialRefreshHeader(HorizontalRefreshLayout.END), HorizontalRefreshLayout.END)
        mBinding.hrl.isEnable = true
        mBinding.hrl.setRefreshCallback(this)

        if (insomniaType == InsomniaType.T) {
            mBinding.pv.visibility = View.GONE
        }

        return mBinding.root
    }

    override fun createHandler() {
        mBinding.recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrollStateChanged(recyclerView: RecyclerView?, newState: Int) {
                super.onScrollStateChanged(recyclerView, newState)

                if (newState == RecyclerView.SCROLL_STATE_IDLE && isVisi && mAdapter!!.getData().isNotEmpty()) {
                    mBinding.pv.switch()
                    mBinding.item = getCurrentInsomnia()
                    if (insomniaType == InsomniaType.V) {
                        mBinding.pv.setUrl(mBinding.item?.audio!!)
                    }
                }
            }
        })

        mBinding.pv.mPlayListener = object : OnPlayViewStateChangedListener {
            override fun onPlayViewStateChanged(playViewState: PlayViewState) {
                when (playViewState) {
                    PlayViewState.PREVIOUS -> {
                        
                        val currPos = getCurrentPos()
                        if (currPos != null) {
                            if (0 < currPos) {
                                mBinding.recyclerView.smoothScrollToPosition(currPos - 1)
                            }
                        }
                    }
                    PlayViewState.NEXT -> {
                        val currPos = getCurrentPos()
                        if (currPos != null) {
                            if (currPos < mAdapter!!.itemCount - 1) {
                                mBinding.recyclerView.smoothScrollToPosition(currPos + 1)
                            }
                        }
                    }
                }
            }

        }
    }

    override fun onLeftRefreshing() {
        HttpMethods.getHotelService()
                .getMineInsomniaList(insomniaType, insomniaCategory, if (insomniaCategory == null) -1 else 1, null, null, null)
                .compose(RxUtil.applyScheduler())
                .compose(bindToLifecycle())
                .subscribe(object : HttpSubscriber<ListRes<InsomniaHotel>>() {
                    override fun onSuccess(response: ListRes<InsomniaHotel>?) {
                        mAdapter!!.clear()
                        if (!IsEmpty.list(response?.results)) {
                            mAdapter!!.addAll(response?.results)

                            mBinding.item = mAdapter!!.getData()[if (currentPos == 0) 0 else currentPos]
                            if (insomniaType == InsomniaType.V) {
                                mBinding.pv.setUrl(mAdapter!!.getData()[if (currentPos == 0) 0 else currentPos].audio)
                            }
                        }
                    }

                    override fun onFailure(errMsg: String?, response: ListRes<InsomniaHotel>?, code: Int) {
                        DialogUtil.showError(mContext, errMsg)
                    }

                    override fun onFinish() {
                        super.onFinish()
                        mBinding.hrl.onRefreshComplete()
                    }
                })
    }

    override fun onRightRefreshing() {
        if (mAdapter!!.getData().isNotEmpty()) {
            newQueryParam.lastId = mAdapter!!.getData().last().id
        }

        HttpMethods.getHotelService()
                .getMineInsomniaList(insomniaType, insomniaCategory, if (insomniaCategory == null) -1 else 1, newQueryParam.lastId, newQueryParam.direction, null)
                .compose(RxUtil.applyScheduler())
                .compose(bindToLifecycle())
                .subscribe(object : HttpSubscriber<ListRes<InsomniaHotel>>() {
                    override fun onSuccess(response: ListRes<InsomniaHotel>?) {
                        if (IsEmpty.list(response?.results)) {
                            ToastUtil.showShort(getString(R.string.hotel_browse_refresh_warning))
                        } else {
                            mAdapter!!.addAll(response?.results)
                        }
                    }

                    override fun onFailure(errMsg: String?, response: ListRes<InsomniaHotel>?, code: Int) {
                        DialogUtil.showError(mContext, errMsg)
                    }

                    override fun onFinish() {
                        super.onFinish()
                        mBinding.hrl.onRefreshComplete()
                    }
                })
    }

    override fun loadData(savedInstanceState: Bundle?) {
        mBinding.hrl.startAutoRefresh(true)
    }

    fun getCurrentPos(): Int? {
        return mBinding.recyclerView.getChildAdapterPosition(mPagerSnapHelper.findSnapView(mLayoutManager))
    }

    fun getCurrentInsomnia(): InsomniaHotel? {
        currentPos = mBinding.recyclerView.getChildAdapterPosition(mPagerSnapHelper.findSnapView(mLayoutManager))
        return mAdapter!!.getData()[currentPos]
    }

    fun getCurrentRecordId(): Int? {
        return getCurrentInsomnia()?.id
    }

    inner class Presenter : BaseViewAdapter.Presenter {
        fun onComment(item: InsomniaHotel?) {
            if (item != null) {
                

                openActivityForResult(mContext as BaseActivity, item.id, Consumer {
                    if (it.resultCode() == Activity.RESULT_OK) {
                        val delta = it.data().getIntExtra("delta", 0)
                        val commentNumObservable = mBinding.item?.commentNumObservable
                        if (delta != 0) {
                            commentNumObservable?.set(
                                    if (commentNumObservable.get() + delta > 0) commentNumObservable.get() + delta else 0
                            )

                        }
                    }
                })
            }
        }

        fun heartInsomnia(item: InsomniaHotel?) {
            if (item != null) {
                val heart = if (item.heart.isHearted) -1 else 1
                val heartInsomniaReq = HeartInsomniaReq(item.id, heart)
                HttpMethods.getHotelService()
                        .heartInsomnia(heartInsomniaReq)
                        .compose(RxUtil.applyScheduler())
                        .compose(bindToLifecycle())
                        .subscribe(object : HttpSubscriber<InsomniaHotel>() {
                            override fun onSuccess(response: InsomniaHotel?) {
                                item.heart = response?.heart
                                mBinding.invalidateAll()








                            }

                            override fun onFailure(errMsg: String?, response: InsomniaHotel?, code: Int) {
                                DialogUtil.showError(mContext, errMsg)
                            }
                        })
            }
        }

        fun onSubscribe(item: InsomniaHotel) {
            if (item.isIs_subscribe) {
                HttpMethods.getHotelService()
                        .unsubscribeUser(item.owner.id)
                        .compose(RxUtil.applyScheduler())
                        .compose(bindToLifecycle())
                        .subscribe(object : HttpSubscriber<PlaceHolder>() {
                            override fun onSuccess(response: PlaceHolder?) {
                                item.isIs_subscribe = false
                                var hotelBrowseActivity = activity as HotelBrowseActivity
                                hotelBrowseActivity.changeAllSubscribe(item)
                                ToastUtil.showShort(getString(R.string.hotel_browse_cancel_subscribe))
                            }

                            override fun onFailure(errMsg: String?, response: PlaceHolder?, code: Int) {
                                DialogUtil.showError(mContext, errMsg)
                            }

                        })
            } else {
                HttpMethods.getHotelService()
                        .subscribeUser(SubscribeReq(item.owner.id))
                        .compose(RxUtil.applyScheduler())
                        .compose(bindToLifecycle())
                        .subscribe(object : HttpSubscriber<PlaceHolder>() {
                            override fun onSuccess(response: PlaceHolder?) {
                                item.isIs_subscribe = true
                                var hotelBrowseActivity = activity as HotelBrowseActivity
                                hotelBrowseActivity.changeAllSubscribe(item)
                                ToastUtil.showShort(getString(R.string.hotel_browse_ok_subscribe))
                            }

                            override fun onFailure(errMsg: String?, response: PlaceHolder?, code: Int) {
                                DialogUtil.showError(mContext, errMsg)
                            }
                        })
            }
        }

        fun onFav(item: InsomniaHotel?) {
            if (item != null) {
                if (item.isIs_favorite) {
                    HttpMethods.getHotelService()
                            .deleteHotelFav(item.id)
                            .compose(RxUtil.applyScheduler())
                            .compose(bindToLifecycle())
                            .subscribe(object : HttpSubscriber<PlaceHolder>() {
                                override fun onSuccess(response: PlaceHolder?) {
                                    item.isIs_favorite = false
                                    mBinding.invalidateAll()
                                    ToastUtil.showShort(getString(R.string.hotel_browse_cancel_collect))

                                }

                                override fun onFailure(errMsg: String?, response: PlaceHolder?, code: Int) {
                                    DialogUtil.showError(mContext, errMsg)
                                }

                            })
                } else {
                    HttpMethods.getHotelService()
                            .addHotelFav(AddHotelFavReq(item.id))
                            .compose(RxUtil.applyScheduler())
                            .compose(bindToLifecycle())
                            .subscribe(object : HttpSubscriber<PlaceHolder>() {
                                override fun onSuccess(response: PlaceHolder?) {
                                    item.isIs_favorite = true
                                    mBinding.invalidateAll()
                                    ToastUtil.showShort(getString(R.string.hotel_browse_ok_collect))
                                }

                                override fun onFailure(errMsg: String?, response: PlaceHolder?, code: Int) {
                                    DialogUtil.showError(mContext, errMsg)
                                }
                            })
                }
            }
        }

        fun jump2Profile(insomniaHotel: InsomniaHotel) {
            val whichProfile = insomniaHotel.owner
            val myId = ProfileUtil.getUserId()
            if (myId != null && whichProfile.id == myId) {
                ProfileActivity.openActivity(mContext)
            } else {
                OtherProfileActivity.openActivity(mContext, whichProfile)
            }

        }
    }

    override fun onDestroy() {
        mBinding.pv.onDestroy()
        super.onDestroy()
    }

    object Util {
        @JvmStatic
        fun getHeartNum(item: InsomniaHotel?): String {
            return item?.heart?.count?.toString() ?: "0"
        }

        @JvmStatic
        fun getHeartChecked(item: InsomniaHotel?): Boolean {
            return item?.heart?.isHearted ?: false
        }

        @JvmStatic
        fun getCommentNum(num: Int?): String {
            return num.toString() ?: "0"
        }

        @JvmStatic
        fun getIsFav(item: InsomniaHotel?): Boolean {
            return item?.isIs_favorite ?: false
        }

        @JvmStatic
        fun getSubscribeText(item: InsomniaHotel): String {
            val res = App.getInstance().resources
            return if (item.isIs_subscribe) res.getString(R.string.hotel_browse_subscribe_state_ok) else res.getString(R.string.hotel_browse_subscribe_state_cancel)
        }
    }

    fun changeAllSubscribe(item: InsomniaHotel) {
        mAdapter?.changeSubscribe(item)
    }

}